home *** CD-ROM | disk | FTP | other *** search
/ Aminet 19 / Aminet 19 (1997)(GTI - Schatztruhe)[!][Jun 1997].iso / Aminet / dev / c / vbcc.lha / vbcc / frontend / vc.c
Encoding:
C/C++ Source or Header  |  1997-01-13  |  13.4 KB  |  427 lines

  1. /*  Frontend for vbcc                       */
  2. /*  (c) in 1995-96 by Volker Barthelmann    */
  3. /*  #define AMIGA for Amiga-Version         */
  4.  
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8.  
  9. #ifdef AMIGA
  10. #include <dos/dos.h>
  11. #include <dos/dosasl.h>
  12. #include <exec/libraries.h>
  13. #include <clib/dos_protos.h>
  14.  
  15. extern struct Library *DOSBase;
  16.  
  17. /*  Must be 32bit-aligned - I know it will be if compiled with vbcc.    */
  18. struct FileInfoBlock fib;
  19. #endif
  20.  
  21. struct NameList{
  22.     struct NameList *next;
  23.     char *obj;
  24. } *first_obj=0,*last_obj=0,*first_scratch=0,*last_scratch=0;
  25.  
  26. /*  Limit fuer Laenge der Namen (wegen Wildcards)   */
  27. #define NAMEBUF 1000    /*  MUST BE >= ~TMPNAM_L+7  */
  28. #define USERLIBS 1000
  29.  
  30. /*  Ab dieser Laenge werden Objektfiles nicht direkt uebergeben,    */
  31. /*  sondern aus einem File an den Linker uebergeben                 */
  32. #ifdef AMIGA
  33. #define MAXCLEN 500
  34. #else
  35. #define MAXCLEN 32000
  36. #endif
  37.  
  38. #define NOTMPFILE 2048
  39. #define OUTPUTSET 1024
  40. #define NOSTDLIB 512
  41. #define VERBOSE 256
  42. #define VERYVERBOSE 128
  43. #define KEEPSCRATCH 64
  44.  
  45. #define PPSRC 1
  46. #define CCSRC 2
  47. #define ASSRC 3
  48. #define OBJ 4
  49.  
  50. char empty[]="";
  51. /*  Namen der einzelnen Phasen  */
  52. char *ppname=empty,*ccname=empty,*asname=empty,*ldname=empty,*l2name=empty,*rmname=empty;
  53. /*  dasselbe fuer VERBOSE   */
  54. char *ppv=empty,*ccv=empty,*asv=empty,*ldv=empty,*l2v=empty,*rmv=empty;
  55.  
  56. #ifdef AMIGA
  57. const char *config_names[]={"vc.config","ENV:vc.config","VBCC:vc.config"};
  58. #else
  59. const char *config_names[]={"vc.config","/etc/vc.config"};
  60. #endif
  61.  
  62. /*  String fuer die Default libraries   */
  63. char userlibs[USERLIBS];
  64. char *nomem="Not enough memory!\n";
  65.  
  66. char *destname="a.out";
  67. char namebuf[NAMEBUF+1],namebuf2[NAMEBUF+1];
  68. char oldfile[NAMEBUF+2];
  69.  
  70. char *config;
  71. char **confp;
  72.  
  73. int typ(char *);
  74. char *add_suffix(char *,char *);
  75. void raus(int);
  76.  
  77. char *command,*options,*linkcmd,*objects,*libs,*ppopts;
  78. #ifdef AMIGA
  79. struct AnchorPath *ap;
  80. #endif
  81.  
  82. int linklen=10,flags=0;
  83.  
  84. void free_namelist(struct NameList *p)
  85. {
  86.     struct NameList *m;
  87.     while(p){
  88.         m=p->next;
  89.         if(flags&VERYVERBOSE){
  90.             puts("free p->obj");
  91.             if(!p->obj) puts("IS ZERO!!"); else puts(p->obj);
  92.         }
  93.         free((void *)p->obj);
  94.         if(flags&VERYVERBOSE){puts("free p"); if(!p) puts("IS ZERO!!");}
  95.         free((void *)p);
  96.         p=m;
  97.     }
  98. }
  99. void del_scratch(struct NameList *p)
  100. {
  101.     while(p){
  102.         sprintf(command,rmname,p->obj);
  103.         if(flags&VERBOSE) printf("%s\n",command);
  104.         if(system(command)){printf("%s failed\n",command);raus(20);}
  105.         p=p->next;
  106.     }
  107. }
  108. void raus(int rc)
  109. {
  110.     if(confp)   free(confp);
  111.     if(config)  free(config);
  112.     if(objects) free(objects);
  113.     if(libs)    free(libs);
  114.     if(command) free(command);
  115.     if(ppopts)  free(ppopts);
  116.     if(options) free(options);
  117.     if(linkcmd) free(linkcmd);
  118. #ifdef AMIGA
  119.     if(ap) free(ap);
  120. #endif
  121.     free_namelist(first_obj);
  122.     free_namelist(first_scratch);
  123.     exit(rc);
  124. }
  125. void add_name(char *obj,struct NameList **first,struct NameList **last)
  126. {
  127.     struct NameList *new;
  128.     if(flags&VERYVERBOSE) printf("add_name: %s\n",obj);
  129.     if(!(new=(struct NameList *)malloc(sizeof(struct NameList))))
  130.         {printf(nomem);raus(20);}
  131.     if(!(new->obj=(char *)malloc(strlen(obj)+1)))
  132.         {free((void *)new);printf(nomem);raus(20);}
  133.     if(first==&first_obj) linklen+=strlen(obj)+1;
  134.     strcpy(new->obj,obj);
  135.     new->next=0;
  136.     if(!*first){
  137.         *first=*last=new;
  138.     }else{
  139.         (*last)->next=new;*last=new;
  140.     }
  141. }
  142. int read_config(void)
  143. {
  144.     int i,count; long size;
  145.     char *p;
  146. #ifdef AMIGA
  147.     BPTR file;
  148.     for(i=0;i<sizeof(config_names)/sizeof(config_names[0]);i++){
  149.         file=Lock((STRPTR)config_names[i],-2);
  150.         if(file) break;
  151.     }
  152.     if(!file) {puts("No config file!");raus(EXIT_FAILURE);}
  153.     if(!Examine(file,&fib)){puts("Examine() failed!");raus(EXIT_FAILURE);}
  154.     size=fib.fib_Size;
  155.     config=malloc(size);
  156.     if(!config){printf(nomem);raus(EXIT_FAILURE);}
  157.     UnLock(file);
  158.     file=Open((STRPTR)config_names[i],MODE_OLDFILE);
  159.     if(!file) return(0);
  160.     size=Read(file,config,size);
  161.     Close(file);
  162. #else
  163.     FILE *file;
  164.     for(i=0;i<sizeof(config_names)/sizeof(config_names[0]);i++){
  165.         file=fopen(config_names[i],"rb");
  166.         if(file) break;
  167.     }
  168.     if(!file) {puts("No config file!");raus(EXIT_FAILURE);}
  169.     if(fseek(file,0,SEEK_END)) return(0);
  170.     size=ftell(file);   /*  noch errorcheck */
  171.     if(fseek(file,0,SEEK_SET)) return(0);
  172.     config=malloc(size);
  173.     if(!config){printf(nomem);raus(EXIT_FAILURE);}
  174.     fread(config,1,size,file);
  175.     fclose(file);
  176. #endif
  177.     count=0;p=config;
  178.     while(*p&&p<config+size){
  179.         count++;
  180.         while(*p!='\n'&&p<config+size) p++;
  181.         if(*p=='\n') *p++=0;
  182.     }
  183.     confp=malloc(count*sizeof(char *));
  184.     for(p=config,i=0;i<count;i++){
  185.         confp[i]=p;
  186.         while(*p) p++;
  187.         p++;
  188.     }
  189.     return(count);
  190. }
  191.  
  192. int main(int argc,char *argv[])
  193. {
  194.     int tfl,i,opt=1,len=10,pm,count;char *parm;
  195.     if(argc>=2&&argv[1][0]=='+'){
  196.         config_names[0]=argv[1]+1;argv[1][0]=0;
  197.     }
  198.     count=read_config();
  199. #ifdef AMIGA
  200.     if(pm=DOSBase->lib_Version>=36){
  201.         if(ap=(struct AnchorPath *)calloc(sizeof(struct AnchorPath)+NAMEBUF,1))
  202.             {ap->ap_Strlen=NAMEBUF;ap->ap_BreakBits=0;} else pm=0;
  203.     }
  204. #endif
  205.     for(i=1;i<argc+count;i++){
  206.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  207. /*        printf("Parameter %d=%s\n",i,parm);*/
  208.         if(!strncmp(parm,"-pp=",4)){ppname=parm+4;*parm=0;}
  209.         if(!strncmp(parm,"-cc=",4)){ccname=parm+4;*parm=0;}
  210.         if(!strncmp(parm,"-as=",4)){asname=parm+4;*parm=0;}
  211.         if(!strncmp(parm,"-ld=",4)){ldname=parm+4;*parm=0;}
  212.         if(!strncmp(parm,"-l2=",4)){l2name=parm+4;*parm=0;}
  213.         if(!strncmp(parm,"-rm=",4)){rmname=parm+4;*parm=0;}
  214.         if(!strncmp(parm,"-ppv=",5)){ppv=parm+5;*parm=0;}
  215.         if(!strncmp(parm,"-ccv=",5)){ccv=parm+5;*parm=0;}
  216.         if(!strncmp(parm,"-asv=",5)){asv=parm+5;*parm=0;}
  217.         if(!strncmp(parm,"-ldv=",5)){ldv=parm+5;*parm=0;}
  218.         if(!strncmp(parm,"-l2v=",5)){l2v=parm+5;*parm=0;}
  219.         if(!strncmp(parm,"-rmv=",5)){rmv=parm+5;*parm=0;}
  220.         if(!strcmp(parm,"-notmpfile")) {flags|=NOTMPFILE;*parm=0;}
  221.         if(!strcmp(parm,"-E")) {flags|=CCSRC;*parm=0;}
  222.         if(!strcmp(parm,"-S")) {flags|=ASSRC;*parm=0;}
  223.         if(!strcmp(parm,"-c")) {flags|=OBJ;*parm=0;}
  224.         if(!strcmp(parm,"-v")) {flags|=VERBOSE;*parm=0;}
  225.         if(!strcmp(parm,"-k")) {flags|=KEEPSCRATCH;*parm=0;}
  226.         if(!strcmp(parm,"-vv")) {flags|=VERBOSE|VERYVERBOSE;*parm=0;}
  227.         if(!strcmp(parm,"-nostdlib")) {flags|=NOSTDLIB;*parm=0;}
  228.         if(!strncmp(parm,"-O",2)){
  229.             if(parm[2]=='0') opt=0;
  230.             if(parm[2]=='1'||parm[2]==0) opt=991;
  231.             if(parm[2]=='2') opt=1023;
  232.             if(parm[2]>='3') opt=~0;
  233.             if(parm[2]=='=') opt=atoi(&parm[3]);
  234.             *parm=0;
  235.         }
  236.         if(!strcmp(parm,"-o")&&i<argc-1) {
  237.             *argv[i++]=0;destname=argv[i];
  238.             flags|=OUTPUTSET;argv[i]="";continue;
  239.         }
  240.         if(!strncmp(parm,"-o=",3)){
  241.             destname=parm+3;
  242.             flags|=OUTPUTSET;*parm=0;continue;
  243.         }
  244.         if(parm[0]=='-'&&parm[1]=='l'){
  245.             if((strlen(userlibs)+strlen(parm)+15)>=USERLIBS){puts("Userlibs too long");exit(20);}
  246. #ifdef AMIGA
  247.             strcat(userlibs," vlib:");
  248.             strcat(userlibs,parm+2);
  249.             strcat(userlibs,".lib");
  250. #else
  251.             strcat(userlibs," ");
  252.             strcat(userlibs,parm);
  253. #endif
  254.             *parm=0;continue;
  255.         }
  256.         len+=strlen(parm)+10;
  257.     }
  258.     if(flags&VERBOSE) printf("vc frontend for vbcc (c) in 1995-96 by Volker Barthelmann\n");
  259.     if(!(flags&7)) flags|=5;
  260.     tfl=flags&7;
  261.     if(flags&VERYVERBOSE){ppname=ppv;ccname=ccv;asname=asv;ldname=ldv;rmname=rmv;l2name=l2v;}
  262.     if(flags&NOSTDLIB){ldname=l2name;}
  263.     /*  Nummer sicher...    */
  264.     len+=strlen(ppname)+strlen(ccname)+strlen(asname)+strlen(rmname)+strlen(userlibs)+NAMEBUF;
  265.     if(!(command=malloc(len))){printf(nomem);raus(20);}
  266.     if(!(options=malloc(len))){printf(nomem);raus(20);}
  267.     if(!(ppopts=malloc(len))){printf(nomem);raus(20);}
  268.     *options=0;*ppopts=0;
  269.     for(i=1;i<argc+count;i++){
  270.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  271.         if(*parm=='-'){
  272.             if(parm[1]!='D'&&parm[1]!='I'&&parm[1]!='+'){
  273.                 strcat(options,parm);strcat(options," ");
  274.             }else{
  275.                 strcat(ppopts,parm);strcat(ppopts," ");
  276.             }
  277.         }
  278.     }
  279.     if(flags&VERYVERBOSE) printf("flags=%d opt=%d len=%d\n",flags,opt,len);
  280.     namebuf[0]='\"'; namebuf2[0]='\"';
  281.     for(i=1;i<argc;i++){
  282.         int t,j;char *file;
  283. #ifdef AMIGA
  284.         BPTR lock;
  285. #endif
  286.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  287.         if(*parm=='-'||!*parm) continue;
  288.         if(flags&VERYVERBOSE) printf("Argument %d:%s\n",i,parm);
  289. #ifdef AMIGA
  290.         if(pm) if(MatchFirst((STRPTR)parm,ap)) {printf("No match for %s\n",parm);continue;}
  291. #endif
  292.         do{
  293. #ifdef AMIGA
  294.             if(pm) file=(char *)&ap->ap_Buf[0]; else file=parm;
  295.             t=typ(file);
  296.             if(pm&&(lock=Lock((STRPTR)file,-2))){
  297.                 NameFromLock(lock,(STRPTR)namebuf+1,NAMEBUF-2);
  298.                 strcat(namebuf,"\"");
  299.                 file=namebuf;
  300.                 UnLock(lock);
  301.             }else{
  302.                 strcpy(namebuf+1,file);
  303.                 strcat(namebuf,"\"");
  304.                 file=namebuf;
  305.             }
  306. #else
  307.             file=parm;
  308.             t=typ(file);
  309.             strcpy(namebuf+1,file);
  310.             strcat(namebuf,"\"");
  311.             file=namebuf;
  312. #endif
  313.             if(flags&VERYVERBOSE) printf("File %s=%d\n",file,t);
  314.             for(j=t;j<tfl;j++){
  315.                 if(j==OBJ){ if(j==t) add_name(file,&first_obj,&last_obj);
  316.                             continue;}
  317.                 strcpy(oldfile,file);
  318.                 if(j==t&&j!=tfl-1&&!(flags&(NOTMPFILE|KEEPSCRATCH))){
  319.                     file=namebuf2;
  320.                     tmpnam(file+1);
  321.                 }
  322.                 if(j==tfl-1) file=namebuf;
  323.                 if(j==PPSRC){
  324.                     file=add_suffix(file,".i");
  325.                     if(tfl==CCSRC&&(flags&OUTPUTSET)) file=destname;
  326.                     sprintf(command,ppname,ppopts,oldfile,file);
  327.                     if((tfl)!=CCSRC) add_name(file,&first_scratch,&last_scratch);
  328.                 }
  329.                 if(j==CCSRC){
  330.                     file=add_suffix(file,".asm");
  331.                     if(tfl==ASSRC&&(flags&OUTPUTSET)) file=destname;
  332.                     sprintf(command,"%s -O=%-4d %s %s -o= %s",ccname,opt,options,oldfile,file);
  333.                     if((tfl)!=ASSRC) add_name(file,&first_scratch,&last_scratch);
  334.                 }
  335.                 if(j==ASSRC){
  336.                     file=add_suffix(file,".o");
  337.                     if(tfl==OBJ&&(flags&OUTPUTSET)) file=destname;
  338.                     sprintf(command,asname,oldfile,file);
  339.                     add_name(file,&first_obj,&last_obj);
  340.                     if((tfl)!=OBJ) add_name(file,&first_scratch,&last_scratch);
  341.                 }
  342.                 if(flags&VERBOSE) printf("%s\n",command);
  343.                 if(system(command)){printf("%s failed\n",command);raus(20);}
  344.             }
  345. #ifdef AMIGA
  346.         }while(pm&&!MatchNext(ap));
  347.         if(pm) MatchEnd(ap);
  348. #else
  349.         }while(0);
  350. #endif
  351.     }
  352.     if((tfl)>OBJ){
  353.     /*  Zu Executable linken    */
  354.         struct NameList *p;
  355.         FILE *objfile=0;
  356.         objects=malloc(linklen);
  357.         if(!objects){printf(nomem);raus(EXIT_FAILURE);}
  358.         linklen+=strlen(ldname)+strlen(destname)+strlen(userlibs)+10;
  359.         if(flags&VERYVERBOSE) printf("linklen=%d\n",linklen);
  360.         if(!(linkcmd=(char *)malloc(linklen))){printf(nomem);raus(20);}
  361.         p=first_obj;
  362.         if(linklen>=MAXCLEN){
  363.             strcpy(objects+1,tmpnam(0));
  364.             *objects='@';
  365.             if(!(objfile=fopen(objects+1,"w"))){
  366.                 printf("Could not open <%s>!\n",objects+1);
  367.                 raus(20);
  368.             }
  369.         }else *objects=0;
  370.         while(p){
  371.             if(p->obj){
  372.                 if(linklen>=MAXCLEN){
  373.                     fputs(p->obj,objfile);
  374.                     fputs("\n",objfile);
  375.                 }else{
  376.                     strcat(objects,p->obj);strcat(objects," ");
  377.                 }
  378.             }
  379.             p=p->next;
  380.         }
  381.         if(objfile) fclose(objfile);
  382.         if(*objects){
  383.             sprintf(linkcmd,ldname,objects,userlibs,destname);
  384.             if(flags&VERBOSE) printf("%s\n",linkcmd);
  385.             /*  hier wird objfile bei Fehler nicht geloescht    */
  386.             if(system(linkcmd)){printf("%s failed\n",linkcmd);raus(20);}
  387. #ifdef AMIGA
  388.             if(flags&VERBOSE){
  389.                 BPTR l;
  390.                 if(l=Lock((STRPTR)destname,-2)){
  391.                     if(Examine(l,&fib)) printf("Size of executable: %lu bytes\n",(unsigned long)fib.fib_Size);
  392.                     UnLock(l);
  393.                 }
  394.             }
  395. #endif
  396.         }else puts("No objects to link");
  397.         if(objfile) remove(objects+1);
  398.     }
  399.     if(!(flags&KEEPSCRATCH)) del_scratch(first_scratch);
  400.     raus(0);
  401. }
  402.  
  403. int typ(char *p)
  404. {
  405.     p=strrchr(p,'.');
  406.     if(!p) return(5);
  407.     if(!strcmp(p,".c")) return(PPSRC);
  408.     if(!strcmp(p,".i")) return(CCSRC);
  409.     if(!strcmp(p,".s")) return(ASSRC);
  410.     if(!strcmp(p,".asm")) return(ASSRC);
  411.     if(!strcmp(p,".o")) return(OBJ);
  412.     if(!strcmp(p,".obj")) return(OBJ);
  413.     return(5);
  414. }
  415.  
  416. char *add_suffix(char *s,char *suffix)
  417. {
  418.     static char str[NAMEBUF+3],*p;
  419.     if(strlen(s)+strlen(suffix)>NAMEBUF){printf("string too long\n");raus(20);}
  420.     if(s!=str) strcpy(str,s);
  421.     p=strrchr(str,'.');
  422.     if(!p) p=str+strlen(s);
  423.     strcpy(p,suffix);
  424.     strcat(p,"\"");
  425.     return(str);
  426. }
  427.